import * as vscode from "vscode";
import * as path from "path";
import * as fs from 'fs';

import {checkDir,
    getConfiguration,
    setConfiguration,
    getFileExtensionFromPath,
    getFileNameFromPath,
    getFileTextFromPath,
    divideTheChapter,
    saveStringToTxt,
    generateUniqueID
} from "../util/util";
import {setStoreJson,getStoreJson} from "../util/store";
import DetailProvider from "./DetailProvider";
import {Novels,Chapter} from "../@types/index";
const ejs = require('ejs');

class SidebarProvider implements vscode.WebviewViewProvider{
    public viewType = 'slidebar-panel';
    private context:vscode.ExtensionContext; //上下文
    private webviewPanel!: vscode.WebviewView;  //侧边栏webview面板
    public detailProvider:any; //详情webview实例

    constructor(context:vscode.ExtensionContext) { 
        this.context = context;
        this.detailProvider = new DetailProvider(context,this);
    }

    /**
     * 加载面板
     * @param webviewView 
     */
    public async resolveWebviewView (webviewView:vscode.WebviewView) {
        webviewView.webview.options = {
            enableScripts: true
        };
        this.webviewPanel = webviewView;
        this.refreshWebviewView();
        webviewView.webview.onDidReceiveMessage(this.onDidReceiveMessage,this);

    }

    /**
     * 获取基础模板
     * @returns 
     */
    public getTemplate () {
        let tplPath = path.join(this.context.extensionPath, path.join('static', 'template', 'sidebar.html'));
        let html = fs.readFileSync(tplPath, 'utf-8');
        html =  html.replace(/(@)(.+?)"/g, (m:any, $1:any, $2:any) => {
            const onDiskPath = vscode.Uri.joinPath(this.context.extensionUri, 'static', $2);
            const resourceSrc = this.webviewPanel ? this.webviewPanel.webview.asWebviewUri(onDiskPath) : '"';
            return resourceSrc + '"';
        });
        return html;
    }

    /**
     * 刷新侧边栏
     * @param list 
     */
    public async refreshWebviewView(list?:Novels[]){
        const novelsList = list ? list : await getStoreJson(this.context.globalStorageUri,"novels_list");
        let data = {
            novelsList:novelsList
        }
        let html = this.getTemplate();
        this.webviewPanel.webview.html = ejs.render(html, data);
    }


    /**
     * 监控webview消息
     * @param data 
     * @returns 
     */
    public async onDidReceiveMessage(data:any){
        switch (data.command) {
            case "message" :{ //页面消息返回
                vscode.window.showInformationMessage(data.data);
                break;
            }
            case "add" :{  //添加小说
                let rootDirectory = this.context.globalStorageUri.fsPath.split(":")[0];
                let storeDir:any = getConfiguration("storeDir");
                if(!storeDir){
                    vscode.window.showErrorMessage("请先设置文件存放目录");
                    vscode.window.showOpenDialog({
                        canSelectFiles:false,
                        canSelectFolders:true,
                        defaultUri:vscode.Uri.file(rootDirectory)
                    }).then(res=>{
                        if(res && res.length){
                            setConfiguration("storeDir",res[0].fsPath);
                        }
                    });
                    return false;
                }
                const novelsList = await getStoreJson(this.context.globalStorageUri,"novels_list");
                vscode.window.showOpenDialog({
                    defaultUri:vscode.Uri.file(rootDirectory),
                    filters:{
                        txt:['txt']
                    }
                }).then(res=>{
                    if(res && res[0]){
                        let extension = getFileExtensionFromPath(res[0].fsPath);
                        if(extension !== 'txt'){
                            vscode.window.showErrorMessage("请选择txt文件");
                            return false;
                        }
                        let novelsName = getFileNameFromPath(res[0].fsPath);
                        if(novelsList && novelsList.findIndex((item:Novels) => item.name === novelsName) >= 0){
                            vscode.window.showErrorMessage("已添加重名的小说");
                            return false;
                        }
                        console.log("res[0]",res[0])
                        this.addNovels(res[0]);
                    }
                })
                break;
            }
            case "detail" :{ //打开详情
                const novelsList = await getStoreJson(this.context.globalStorageUri,"novels_list");
                const novels = novelsList[data.data];
                this.detailProvider.showWebviewPanel(novels);
                break;
            }
            case "delete" :{ //删除小说
                let novelsList = await getStoreJson(this.context.globalStorageUri,"novels_list");
                if(this.webviewPanel && novelsList[data.data]){
                    this.webviewPanel.webview.postMessage({ command: 'loading' });
                    let deleteId = novelsList[data.data].id;
                    if(this.detailProvider && this.detailProvider.novels && this.detailProvider.novels.id === deleteId){
                        this.detailProvider.disposeWebviewPanel();
                    }
                    let novelsPath = vscode.Uri.file(novelsList[data.data].path);
                    let chapterPath = vscode.Uri.file(novelsList[data.data].chapterPath);
                    novelsList.splice(data.data,1);
                    await setStoreJson(this.context.globalStorageUri,"novels_list",novelsList);
                    await vscode.workspace.fs.delete(novelsPath,{recursive:true});
                    await vscode.workspace.fs.delete(chapterPath);
                    this.refreshWebviewView();
                }

                break;
            }
            case "test" :{
                
                break;
            }
            
        }
    }
    
    /**
     * 添加小说
     * @param data 
     */
    public async addNovels(data:vscode.Uri) {
        
        try {
            this.webviewPanel.webview.postMessage({ command: 'loading' })
            let storeDir:any = getConfiguration("storeDir");
            if(!storeDir){
                throw new Error("未设置文件存放目录!")
            }
            await checkDir(storeDir)

            //解析文件分隔成列表
            let novelsText = await getFileTextFromPath(data.fsPath);
            let novelsArray = divideTheChapter(novelsText);
            if(novelsText &&  !novelsArray.length) {
                throw new Error("无法分割文件，请检查txt的章节格式!");
            }
            // console.log("novelsArray",novelsText)
            let novelsName = getFileNameFromPath(data.fsPath);
            if(!novelsText ||  !novelsArray.length) {
                throw new Error("文件解析错误!");
            }

            
            let novelsList = await getStoreJson(this.context.globalStorageUri,"novels_list");
            novelsList =  novelsList ? novelsList : [];

            //生成唯一的id
            let novelsId = generateUniqueID(16);

            //目录路径和配置路径
            let novelsPath = vscode.Uri.joinPath(vscode.Uri.file(storeDir),novelsName) //存储位置
            let chapterPath = vscode.Uri.joinPath(this.context.globalStorageUri,"novels_chapter_"+novelsId+'.json'); //目录文件位置

            //将整本小说分隔为单章，存储在指定的文件夹
            let chapter:Chapter[] = [];
            for(let i = 0; i < novelsArray.length; i++){
                let path = vscode.Uri.joinPath(vscode.Uri.file(storeDir),novelsName);
                await saveStringToTxt(path,String(i),novelsArray[i].detail);
                chapter.push({
                    title:novelsArray[i].title,
                    fileName:String(i)+'.txt',
                    filePath:novelsPath.path+"/"+String(i)+'.txt'
                });
            }
            
            //修改配置
            let novels:Novels = {
                id:novelsId,
                name:novelsName,
                path:novelsPath.path,
                chapterPath:chapterPath.path,
                chapterLength:chapter.length,
                activeChapterIndex:0,
                activeChapterTitle:chapter[0].title
            }
            novelsList.push(novels);
            await setStoreJson(this.context.globalStorageUri,"novels_list",novelsList);
            await setStoreJson(this.context.globalStorageUri,"novels_chapter_"+novelsId,chapter);
            this.refreshWebviewView();
        } catch (error:any) {
            this.webviewPanel.webview.postMessage({ command: 'loading' });
            console.log("错误",error);
            vscode.window.showErrorMessage(error  ? error.message : "操作失败！");
        }
    }




}

export default SidebarProvider;



// class SidebarViewProvider implements vscode.WebviewViewProvider {

// 	public static readonly viewType = 'cyberloafingRead.sidebar';

// 	private _view?: vscode.WebviewView;

// 	constructor(
// 		private readonly _extensionUri: vscode.Uri,
// 	) { }

// 	public resolveWebviewView(
// 		webviewView: vscode.WebviewView,
// 		context: vscode.WebviewViewResolveContext,
// 		_token: vscode.CancellationToken,
// 	) {
// 		this._view = webviewView;

// 		webviewView.webview.options = {
// 			// Allow scripts in the webview
// 			enableScripts: true,
// 			localResourceRoots: [
// 				this._extensionUri
// 			]
// 		};

// 		webviewView.webview.html = this._getHtmlForWebview(webviewView.webview);

// 		webviewView.webview.onDidReceiveMessage(data => {
// 			switch (data.type) {
// 				case 'colorSelected':
// 					{
// 						vscode.window.activeTextEditor?.insertSnippet(new vscode.SnippetString(`#${data.value}`));
// 						break;
// 					}
// 			}
// 		});
// 	}

// 	public addColor() {
// 		if (this._view) {
// 			this._view.show?.(true); // `show` is not implemented in 1.49 but is for 1.50 insiders
// 			this._view.webview.postMessage({ type: 'addColor' });
// 		}
// 	}

// 	public clearColors() {
// 		if (this._view) {
// 			this._view.webview.postMessage({ type: 'clearColors' });
// 		}
// 	}

// 	private _getHtmlForWebview(webview: vscode.Webview) {
// 		// Get the local path to main script run in the webview, then convert it to a uri we can use in the webview.
// 		// const scriptUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, 'media', 'main.js'));
// 		// // Do the same for the stylesheet.
// 		// const styleResetUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, 'media', 'reset.css'));
// 		// const styleVSCodeUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, 'media', 'vscode.css'));
// 		// const styleMainUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, 'media', 'main.css'));
// 		// Use a nonce to only allow a specific script to be run.
// 		// const nonce = getNonce();
// 		return ``;
// 	}
// }


// const sidebarViewProvider = new SidebarViewProvider();
// export sidebarViewProvider;
